﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace Gmantis.Controls.DataGrid
{
    public class DataGridRowsHeaderPanel : RecyclingPanel
    {
        // Fields
        private int FirstVisibleRow = -1;
        private int LastVisibleRow = -1;

        // Methods
        public DataGridRowsHeaderPanel()
        {
            this.SetCustomDefaultValues();
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            double bottomOffset = finalSize.Height - this.View.ScrollManager.FrozenBottomHeight;
            double frozenTopHeight = this.View.ScrollManager.FrozenTopHeight;
            Math.Min((finalSize.Height - this.View.ScrollManager.FrozenTopHeight) - this.View.ScrollManager.FrozenBottomHeight, this.View.ScrollManager.ExtentHeight);
            foreach (UIElement element in base.Children)
            {
                DataGridRowHeaderPresenter presenter = element as DataGridRowHeaderPresenter;
                if (presenter != null)
                {
                    ViewRow viewRow = presenter.ViewRow;
                    if (viewRow != null)
                    {
                        if (viewRow.Row.IsTopFrozen)
                        {
                            Canvas.SetZIndex(presenter, 0x3e8);
                            presenter.Clip = null;
                        }
                        else if (viewRow.Row.IsBottomFrozen)
                        {
                            Canvas.SetZIndex(presenter, 0x3e7);
                            presenter.Clip = null;
                        }
                        else
                        {
                            Canvas.SetZIndex(presenter, 0x3e6 - (viewRow.Row.Index - this.FirstVisibleRow));
                            base.ClipPresenterHorizontally(presenter, finalSize.Width, viewRow.GetTotalRenderHeight(), frozenTopHeight, bottomOffset, viewRow.Offset);
                        }
                        presenter.Arrange(new Rect(0.0, viewRow.Offset, finalSize.Width, viewRow.GetTotalRenderHeight()));
                    }
                }
            }
            return finalSize;
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            if (!double.IsInfinity(availableSize.Height))
            {
                double num2;
                int rowIndex;
                int rowIndexFromScrollPosition;
                double num = Math.Max((double)0.0, (double)(availableSize.Height - this.View.GetFrozenHeight()));
                FillParameters validFillParameters = this.View.ScrollManager.ValidFillParameters;
                if (validFillParameters.VerticalDirection == GeneratorDirection.Forward)
                {
                    double scrollPositionFromRowIndex = this.View.ScrollManager.GetScrollPositionFromRowIndex(validFillParameters.RowIndex);
                    double num5 = scrollPositionFromRowIndex - validFillParameters.RowOffset;
                    rowIndex = validFillParameters.RowIndex;
                    rowIndexFromScrollPosition = this.View.ScrollManager.GetRowIndexFromScrollPosition(num5 + num, out num2);
                }
                else
                {
                    double introduced21 = this.View.ScrollManager.GetScrollPositionFromRowIndex(validFillParameters.RowIndex + 1);
                    double num6 = introduced21 + validFillParameters.RowOffset;
                    rowIndexFromScrollPosition = validFillParameters.RowIndex;
                    rowIndex = this.View.ScrollManager.GetRowIndexFromScrollPosition(num6 - num, out num2);
                }
                this.RemoveUnusedChildren(rowIndex, rowIndexFromScrollPosition, false);
            }
            double num7 = 0.0;
            for (int i = 0; i < this.View.Model.FrozenTopRowsCount; i++)
            {
                DataGridRow row = this.View.Model.Rows[i];
                if (row.IsVisible(false))
                {
                    ViewRow viewRow = row.ViewRow;
                    viewRow.GetHeaderPresenter(true).Measure(new Size(double.PositiveInfinity, viewRow.GetTotalRenderHeight()));
                    num7 += viewRow.GetTotalRenderHeight();
                }
            }
            for (int j = this.View.Model.Rows.Count - this.View.Model.FrozenBottomRowsCount; j < this.View.Model.Rows.Count; j++)
            {
                DataGridRow row3 = this.View.Model.Rows[j];
                if (row3.IsVisible(false))
                {
                    ViewRow row4 = this.View.Model.Rows[j].ViewRow;
                    row4.GetHeaderPresenter(true).Measure(new Size(double.PositiveInfinity, row4.GetTotalRenderHeight()));
                    num7 += row4.GetTotalRenderHeight();
                }
            }
            this.FirstVisibleRow = Math.Max(0, Math.Min(this.VisibleRows.FirstVisibleItem, this.View.Model.Rows.Count - 1));
            this.LastVisibleRow = Math.Max(0, Math.Min(this.VisibleRows.LastVisibleItem, this.View.Model.Rows.Count - 1));
            if (this.View.Model.Rows.Count > 0)
            {
                this.RemoveUnusedChildren(this.FirstVisibleRow, this.LastVisibleRow, true);
                for (int k = this.FirstVisibleRow; k <= this.LastVisibleRow; k++)
                {
                    DataGridRow row5 = this.View.Model.Rows[k];
                    if (row5.IsVisible(false))
                    {
                        ViewRow row6 = row5.ViewRow;
                        row6.GetHeaderPresenter(true).Measure(new Size(double.PositiveInfinity, row6.GetTotalRenderHeight()));
                        num7 += row6.GetTotalRenderHeight();
                    }
                }
            }
            else
            {
                this.RemoveAllChildren();
            }
            return new Size(availableSize.Width, (num7 < availableSize.Height) ? num7 : availableSize.Height);
        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            Size newSize = e.NewSize;
            RectangleGeometry geometry = new RectangleGeometry
            {
                Rect = new Rect(0.0, 0.0, newSize.Width, newSize.Height)
            };
            base.Clip = geometry;
        }

        private void RemoveAllChildren()
        {
            foreach (UIElement element in new List<UIElement>(base.Children.GetTypedUIElementCollectionWrapper()))
            {
                DataGridRowHeaderPresenter child = element as DataGridRowHeaderPresenter;
                if ((child != null) && !child.IsCollected)
                {
                    this.RemoveChild(child);
                }
            }
        }

        private void RemoveUnusedChildren(int firstRowIndex, int lastRowIndex, bool measureCollectedChildren)
        {
            foreach (UIElement element in new List<UIElement>(base.Children.GetTypedUIElementCollectionWrapper()))
            {
                DataGridRowHeaderPresenter child = element as DataGridRowHeaderPresenter;
                if (child != null)
                {
                    if (!child.IsCollected)
                    {
                        bool flag = false;
                        if (child.ViewRow == null)
                        {
                            flag = true;
                        }
                        else
                        {
                            ViewRow viewRow = child.ViewRow;
                            DataGridRow row = viewRow.Row;
                            int index = row.Index;
                            if ((((index < firstRowIndex) || (index > lastRowIndex)) && !viewRow.Row.IsFrozen) || !row.IsVisible(false))
                            {
                                flag = true;
                            }
                        }
                        if (flag)
                        {
                            this.RemoveChild(child);
                        }
                    }
                }
                else if (measureCollectedChildren)
                {
                    child.Measure(new Size(0.0, 0.0));
                }
            }
        }

        private void SetCustomDefaultValues()
        {
            base.SizeChanged += new SizeChangedEventHandler(this.OnSizeChanged);
        }

        // Properties
        internal DataGridView View { get; set; }

        private DataGridVisibleItems<DataGridRow> VisibleRows
        {
            get
            {
                return this.View.Viewport.VisibleRows;
            }
        }
    }
}
